/**
 * 自定义plugin，处理css和scss文件
 * 添加兼容
 * 压缩
 * */

const sass = require('sass')
const autoprefixer = require('autoprefixer')
const postcss = require('postcss')


class MyCssPlugin {
  constructor(options) {
    // console.log(options);
    this.options = options

    // 计算输出文件的路径和文件名，以及修改后缀
    this.outFileName = options.filePath.replace(options.srcPath, '')
    this.outFileName = this.outFileName.replace(/\.(css|scss|sass)$/, '.css')
    this.outFileName = this.outFileName.replace(/^\\/, '').replace(/\\/g, '/')
  }

  apply(compiler) {
    let This = this

    // 监听文件修改，默认情况下 Webpack 只会监视入口和其依赖的模块是否发生变化，这里的css属于引入新的文件，需要手动添加到监听列表中。
    compiler.plugin('after-compile', (compilation, callback) => {
      compilation.fileDependencies.add(this.options.filePath)
      callback()
    })

    compiler.plugin('compile', () => {
      // console.log('webpack 编译器开始编译...-----')
    })

    compiler.plugin('compilation', (compilation) => {
      // console.log('编译器开始一个新的编译任务...-----')
    })

    compiler.plugin('emit', (compilation, callback) => {
      // console.log('----------------------------------编辑文件')

      let hash = compilation.hash.substring(0, 8)
      let outFileName = This.outFileName.replace(/\.css$/, '.' + hash + '.css')

      // scss处理css
      let scssResult = sass.renderSync({ file: This.options.filePath })

      // css添加兼容前缀
      postcss([autoprefixer]).process(scssResult.css).then(postcssResult => {
        postcssResult.warnings().forEach(warn => {
          console.warn(warn.toString())
        })

        // 将文件插入到新生成的文件队列中，webpack会自动去生成这些文件
        compilation.assets[outFileName] = {
          source: function () {
            return postcssResult.css;
          },
          size: function () {
            return postcssResult.css.length;
          }
        }

        callback()
      })
    })

    compiler.plugin('done', function () {
      // console.log('打包结束......')
    })
  }
}

module.exports = MyCssPlugin;
